package controller

import (
	"api/dao/mysql"
	"api/global"
	"api/helper"
	"api/model"
	"api/tool/captcha"
	"api/tool/jwt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// Login
// @Summary user login
// @Description login
// @Tags Users
// @Accept application/json
// @Produce application/json
// @Param object body model.RequestLogin false "body params"
// @Success 200 {object} model.Response
// @Router /user/login [post]
func Login(c *gin.Context) {
	var request model.RequestLogin

	err := c.ShouldBindJSON(&request)
	if err != nil {
		ResultError(http.StatusOK, UNKOWN, err.Error(), c)
		return
	}

	err = helper.VerifyParams(request)
	if err != nil {
		ResultError(http.StatusOK, PARAMTER, err.Error(), c)
		return
	}

	if global.AppConfig.Mode == "release" {
		err = captcha.VerifyCaptcha(request.CaptchaId, request.CaptchaValue)
		if err != nil {
			ResultError(http.StatusOK, PARAMTER, err.Error(), c)
			return
		}
	}

	user, err := mysql.GetUser("username = ? and enable = ?", request.Username, 0)
	if err != nil {
		ResultError(http.StatusOK, USERNAMEERROR, Msg[USERNAMEERROR], c)
		return
	}
	if user.Password != helper.Md5(request.Password+user.Salt) {
		ResultError(http.StatusOK, PASSWORDERROR, Msg[PASSWORDERROR], c)
		return
	}
	accessToken, refreshToken, err := jwt.GenToken(user.Model.Id, user.Username, int(user.Role.Int16))
	if err != nil {
		ResultError(http.StatusOK, TOKENERROR, Msg[TOKENERROR], c)
		return
	}
	data := map[string]string{
		"access_token":  accessToken,
		"refresh_token": refreshToken,
		"user_id":       user.Id,
		"username":      user.Username,
	}
	ResultWithData(http.StatusOK, SUCCESS, Msg[SUCCESS], data, c)
}

// ReToken
// @Summary get token and refresh token
// @Description login
// @Tags Users
// @Accept application/json
// @Produce application/json
// @Param token header string true "token"
// @Param token header string true "refresh_token"
// @Success 200 {object} model.Response
// @Router /user/re_token [post]
func ReToken(c *gin.Context) {
	var request model.RequestReToken

	err := c.ShouldBindHeader(&request)
	if err != nil {
		ResultError(http.StatusOK, UNKOWN, err.Error(), c)
		return
	}

	err = helper.VerifyParams(request)
	if err != nil {
		ResultError(http.StatusOK, PARAMTER, err.Error(), c)
		return
	}
	newAccessToken, newRefreshToken, err := jwt.RefreshToken(request.Token, request.RefreshToken)
	if err != nil {
		ResultError(http.StatusOK, PARAMTER, Msg[PARAMTER], c)
		return
	}
	data := map[string]string{
		"access_token":  newAccessToken,
		"refresh_token": newRefreshToken,
	}
	ResultWithData(http.StatusOK, SUCCESS, Msg[SUCCESS], data, c)
}

// Users
// @Summary get users
// @Description get users list
// @Tags Users
// @Accept application/json
// @Produce application/json
// @Param token header string true "token"
// @Param object query model.RequestUsers false "query params"
// @Success 200 {object} model.Response
// @Router /user/list [get]
func Users(c *gin.Context) {
	var request model.RequestUsers
	var selects []string = []string{"id", "created_at", "updated_at", "deleted_at", "username", "email", "phone", "role", "app_name", "app_key", "comment", "enable"}

	err := c.ShouldBindQuery(&request)
	if err != nil {
		ResultError(http.StatusOK, UNKOWN, err.Error(), c)
		return
	}

	err = helper.VerifyParams(request)
	if err != nil {
		ResultError(http.StatusOK, PARAMTER, err.Error(), c)
		return
	}

	offset := (request.Page * request.PageSize) * (request.Page - 1)
	limit := request.PageSize
	users, total, err := mysql.GetUsers(offset, limit, selects, &model.User{
		Username: request.Username,
	})

	if err != nil {
		ResultError(http.StatusOK, UNKOWN, err.Error(), c)
		return
	}

	ResultWithData(http.StatusOK, SUCCESS, Msg[SUCCESS], model.ResponseUsersData{
		Page:     request.Page,
		PageSize: request.PageSize,
		Data:     *users,
		Total:    total,
	}, c)
}
